home *** CD-ROM | disk | FTP | other *** search
/ Super PC 34 / Super PC 34 (Shareware).iso / spc / UTIL / DJGPP2 / V2 / DJLSR200.ZIP / src / stub / stubify.c < prev   
Encoding:
C/C++ Source or Header  |  1995-11-05  |  5.7 KB  |  243 lines

  1. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <fcntl.h>
  5. #include <sys/stat.h>
  6. #include <string.h>
  7. #ifdef __DJGPP__
  8. #include <io.h>
  9. #endif
  10.  
  11. #ifndef O_BINARY
  12. #define O_BINARY 0
  13. #endif
  14.  
  15. unsigned char stub_bytes[] = {
  16. #include "stub.h"
  17. };
  18.  
  19. #define v_printf if(verbose)printf
  20. int verbose=0;
  21.  
  22. unsigned long
  23. get32(unsigned char *ptr)
  24. {
  25.   return ptr[0] | (ptr[1]<<8) | (ptr[2]<<16) | (ptr[3]<<24);
  26. }
  27.  
  28. unsigned short
  29. get16(unsigned char *ptr)
  30. {
  31.   return ptr[0] | (ptr[1]<<8);
  32. }
  33.  
  34. void coff2exe(char *fname)
  35. {
  36.   char ifilename[256];
  37.   char ofilename[256];
  38.   int ifile;
  39.   int ofile;
  40.   char *ofname, *ofext;
  41.   char buf[4096];
  42.   int rbytes, used_temp, i, n;
  43.   long coffset=0;
  44.   unsigned char filehdr_buf[20];
  45.   int max_file_size = 0;
  46.   int coff_file_size = 0;
  47.   int drop_last_four_bytes = 0;
  48.  
  49.   strcpy(ifilename, fname);
  50.   strcpy(ofilename, fname);
  51.   ofext = 0;
  52.   for (ofname=ofilename; *ofname; ofname++)
  53.   {
  54.     if (strchr("/\\:", *ofname))
  55.       ofext = 0;
  56.     if (*ofname == '.')
  57.       ofext = ofname;
  58.   }
  59.   if (ofext == 0)
  60.     ofext = ofilename + strlen(ofilename);
  61.   strcpy(ofext, ".exe");
  62.   if (access(ofilename, 0) == 0)
  63.     for (ofile=0; ofile<999; ofile++)
  64.     {
  65.       used_temp = 1;
  66.       sprintf(ofext, ".%03d", ofile);
  67.       if (access(ofilename, 0))
  68.     break;
  69.     }
  70.   else
  71.     used_temp = 0;
  72.  
  73.   ifile = open(ifilename, O_RDONLY|O_BINARY);
  74.   if (ifile < 0)
  75.   {
  76.     perror(fname);
  77.     return;
  78.   }
  79.   while (1)
  80.   {
  81.     lseek(ifile, coffset, 0);
  82.     read(ifile, buf, 6);
  83.     if (buf[0] == 'M' && buf[1] == 'Z') /* stubbed already, skip stub */
  84.     {
  85.       int blocks = (unsigned char)buf[4] + (unsigned char)buf[5] * 256;
  86.       int partial = (unsigned char)buf[2] + (unsigned char)buf[3] * 256;
  87.       coffset += blocks * 512;
  88.       if (partial)
  89.     coffset += partial - 512;
  90.     }
  91.     else if (buf[0] == 0x4c && buf[1] == 0x01) /* it's a COFF */
  92.     {
  93.       break;
  94.     }
  95.     else
  96.     {
  97.       fprintf(stderr, "Warning: input file is not COFF or stubbed COFF\n");
  98.       break;
  99.     }
  100.   }
  101.  
  102.   coff_file_size = lseek(ifile, 0, SEEK_END) - coffset;
  103.   lseek(ifile, coffset, 0);
  104.  
  105.   read(ifile, filehdr_buf, 20); /* get the COFF header */
  106.   lseek(ifile, get16(filehdr_buf+16), SEEK_CUR); /* skip optional header */
  107.   n = get16(filehdr_buf + 2);
  108.   for (i=0; i<n; i++) /* for each COFF section */
  109.   {
  110.     int addr, size, flags;
  111.     unsigned char coffsec_buf[40];
  112.     read(ifile, coffsec_buf, 40);
  113.     size = get32(coffsec_buf+16);
  114.     addr = get32(coffsec_buf+20);
  115.     flags = get32(coffsec_buf+36);
  116.     if (flags & 0x60) /* text or data */
  117.     {
  118.       int maybe_file_size = size + addr;
  119.       if (max_file_size < maybe_file_size)
  120.     max_file_size = maybe_file_size;
  121.     }
  122.   }
  123.   if (coff_file_size == max_file_size + 4)
  124.     /* it was built with "gcc -s" and has four too many bytes */
  125.     drop_last_four_bytes = 1;
  126.  
  127.   lseek(ifile, coffset, 0);
  128.  
  129.   ofile = open(ofilename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
  130.   if (ofile < 0)
  131.   {
  132.     perror(ofname);
  133.     return;
  134.   }
  135.   v_printf("stubify: %s -> %s", ifilename, ofilename);
  136.   if (used_temp)
  137.   {
  138.     strcpy(ifilename, ofilename);
  139.     strcpy(ofext, ".exe");
  140.     v_printf(" -> %s", ofilename);
  141.   }
  142.   v_printf("\n");
  143.  
  144.   write(ofile, stub_bytes, sizeof(stub_bytes));
  145.   
  146.   while ((rbytes=read(ifile, buf, 4096)) > 0)
  147.   {
  148.     int wb;
  149.  
  150.     if (drop_last_four_bytes && rbytes < 4096)
  151.       rbytes -= 4;
  152.  
  153.     wb = write(ofile, buf, rbytes);
  154.     if (wb < 0)
  155.     {
  156.       perror(ofname);
  157.       unlink(ofilename);
  158.       close(ifile);
  159.       close(ofile);
  160.       exit(1);
  161.     }
  162.     if (wb < rbytes)
  163.     {
  164.       fprintf(stderr, "%s: disk full\n", ofname);
  165.       unlink(ofilename);
  166.       close(ifile);
  167.       close(ofile);
  168.       exit(1);
  169.     }
  170.   }
  171.  
  172.   close(ifile);
  173.   close(ofile);
  174.  
  175.   if (used_temp)
  176.   {
  177.     unlink(ofilename);
  178.     if (rename(ifilename, ofilename))
  179.     {
  180.       printf("rename of %s to %s failed.\n", ifilename, ofilename);
  181.       perror("The error was");
  182.     }
  183.   }
  184. }
  185.  
  186. int main(int argc, char **argv)
  187. {
  188.   int i;
  189.   if (argc > 1 && strcmp(argv[1], "-v")==0)
  190.   {
  191.     verbose = 1;
  192.     argv++;
  193.     argc--;
  194.   }
  195.   v_printf("stubify for djgpp V2.X executables, Copyright (C) 1995 DJ Delorie\n");
  196.   if (argc < 2)
  197.   {
  198.     fprintf(stderr, "Usage: stubify [-g] <program>  (program may be COFF or stubbed .exe,\n");
  199.     fprintf(stderr, "  and may be COFF with .exe extension.  Resulting file will have .exe)\n");
  200.  
  201.     fprintf(stderr, "\nThis program is NOT shareware or public domain.  It is copyrighted.\n");
  202.     fprintf(stderr, "It is redistributable but only as part of a complete package.  If you\n");
  203.     fprintf(stderr, "have a copy of this program, the place that you got it from is\n");
  204.     fprintf(stderr, "responsible for making sure you are able to get it's sources as well.\n");
  205.  
  206.     exit(1);
  207.   }
  208.   if (argc > 2 && strcmp(argv[1], "-g") == 0)
  209.   {
  210.     char ofilename[256], *ofname, *ofext=0;
  211.     int ofile;
  212.  
  213.     strcpy(ofilename, argv[2]);
  214.     for (ofname=ofilename; *ofname; ofname++)
  215.     {
  216.       if (strchr("/\\:", *ofname))
  217.     ofext = 0;
  218.       if (*ofname == '.')
  219.     ofext = ofname;
  220.     }
  221.     if (ofext == 0)
  222.       ofext = ofilename + strlen(ofilename);
  223.     strcpy(ofext, ".exe");
  224.     
  225.     ofile = open(ofilename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
  226.     if (ofile < 0)
  227.     {
  228.       printf("Cannot open output file to generate\n");
  229.       perror(ofilename);
  230.       return;
  231.     }
  232.     v_printf("stubify: generate %s\n", argv[2]);
  233.  
  234.     write(ofile, stub_bytes, sizeof(stub_bytes));
  235.     close(ofile);
  236.   }
  237.   else
  238.     for (i=1; i<argc; i++)
  239.       coff2exe(argv[i]);
  240.   return 0;
  241. }
  242.  
  243.